package com.cloudinnov.controller.api;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.cloudinnov.logic.AuthUserLogic;
import com.cloudinnov.logic.CompaniesLogic;
import com.cloudinnov.logic.EquipmentsLogic;
import com.cloudinnov.logic.ProductionLinesLogic;
import com.cloudinnov.model.AuthUsers;
import com.cloudinnov.model.Companies;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.ProductionLines;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.ObjectMappingCustomer;
import com.cloudinnov.utils.PropertiesUtils;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author chengning
 * @date 2016年2月26日上午9:58:34
 * @email ningcheng@cloudinnov.com
 * @remark
 * @version
 */
@Controller
@RequestMapping("/webapi/base")
public class BaseController {

	private static final Logger logger = LoggerFactory.getLogger(BaseController.class);

	@Autowired
	private AuthUserLogic authUserLogic;

	@Autowired
	private CompaniesLogic companiesLogic;

	@Autowired
	private EquipmentsLogic equipmentsLogic;

	@Autowired
	private ProductionLinesLogic productionLinesLogic;

	// token超时
	public static final int LOGIN_ERROR_TOKEN = 10001;

	// 用户名密码验证失败Code
	public static final int LOGIN_ERROR_USER = 10002;

	// 验证码错误
	public static final int LOGIN_ERROR_VERIFYCODE = 10004;
	
	// 验证码超时
	public static final int LOGIN_ERROR_VERIFYCODE_TIMEOUT = 10005;
	
	// 用户名密码验证失败Msg
	public static final String LOGIN_ERROR_USER_MSG = "Auth Error";

	// 验证码错误Msg
	public static final String LOGIN_ERROR_VERIFYCODE_MSG = "verifyCode Is Error";
	
	// 验证码错误Msg
	public static final String LOGIN_ERROR_VERIFYCODE_TIMEOUT_MSG = "verifyCode Is Timeout";

	// 用户原密码错误
	public static final int PASSWORD_VERIFY_ERROR = 10003;
	
	// 手机号不存在
	public static final int LOGIN_ERROR_PHONE_NO_EXIST = 10007;
	
	// 手机号不存在MSG
	public static final String LOGIN_ERROR_PHONE_NO_EXIST_MSG = "Phone Is No Exist";
	
	// 手机号存在
	public static final int LOGIN_ERROR_PHONE_EXIST = 10008;
		
	// 手机号存在MSG
	public static final String LOGIN_ERROR_PHONE_EXIST_MSG = "Phone Is Exist";

	// 成功标示
	public static final int SUCCESS = 1;

	// 失败标示
	public static final int ERROR = 0;

	// 成功提示信息
	public static final String SUCCESS_MSG = "成功";

	// 失败提示信息
	public static final String ERROR_MSG = "失败";

	public static final String CALLBACK = "jsonp_callback";

	public final static int DEFAULT_NUM = 0;

	public final static int DEFAULT_SIZE = 0;

	public final static int DEFAULT_SUCCESS_SIZE = 1;

	public final static String UPLOAD_IMG_PATH = "upload";

	public final static String WINDOWS_UPLOAD_IMG_PATH = PropertiesUtils.findPropertiesKey("upload.windows.path");

	public final static String LINUX_UPLOAD_IMG_PATH = PropertiesUtils.findPropertiesKey("upload.linux.path");

	public static final String USER_LOGO = "userLogo";
	
	public static final String LOGIN_NAME = "loginName";
	
	public static final String USER_NAME = "userName";
	
	public static final String OEM_CODE = "oemCode";

	public static final String INTEGRATOR_CODE = "integratorCode";

	public static final String COM_CODE = "companyCode";

	public static final String USER_CODE = "userCode";

	public static final String USER_TYPE = "userType";
	public static final String DEFAULT_LOGO = "logo";
	public static final String DEFAULT_LOGO_USER = "logo.user";
	public static final String LOGIN_TYPE = "loginType";

	/**
	 * 得到登录用户的信息
	 * 
	 * @param request
	 * @return OEM_CODE oemCode COM_CODE 客户code USER_CODE 用户code USER_TYPE 默认图片
	 *         DEFAULT_LOGO 当前登录用户类型
	 */
	public static Map<String, String> getUserInfo(HttpServletRequest request) {
		Map<String, String> map = new HashMap<String, String>();
		map.put(USER_LOGO, (String) request.getAttribute(USER_LOGO));
		map.put(LOGIN_NAME, (String) request.getAttribute(LOGIN_NAME));
		map.put(USER_NAME, (String) request.getAttribute(USER_NAME));
		map.put(OEM_CODE, (String) request.getAttribute(OEM_CODE));
		map.put(COM_CODE, (String) request.getAttribute(COM_CODE));
		map.put(INTEGRATOR_CODE, (String) request.getAttribute(INTEGRATOR_CODE));
		map.put(USER_CODE, (String) request.getAttribute(USER_CODE));
		map.put(USER_TYPE, (String) request.getAttribute(USER_TYPE));
		map.put(DEFAULT_LOGO, CommonUtils.WEB_ADDRESS + CommonUtils.IMAGE_DEFAULT_PUBLIC);
		map.put(DEFAULT_LOGO_USER, CommonUtils.WEB_ADDRESS + CommonUtils.IMAGE_DEFAULT_USER);
		map.put(LOGIN_TYPE, (String) request.getAttribute(LOGIN_TYPE));
		return map;
	}

	/** 百度语音识别
	 * @Title: voiceRecognition 
	 * @Description: TODO
	 * @param fileType
	 * @param cuid
	 * @param length
	 * @param base64String
	 * @param request
	 * @param response
	 * @throws Exception
	 * @return: void
	 */
	@RequestMapping(value = "/voiceRecognition" ,method = RequestMethod.POST)
	@ResponseBody
	public void voiceRecognition(String fileType, String cuid, long length, String base64String, HttpServletRequest request, HttpServletResponse response) throws Exception {
		List<String> result = CommonUtils.baiduVoiceRecognition(fileType, cuid, length, base64String);
		Map<String, Object> map = new HashMap<String, Object>();
		if (result.size() > DEFAULT_SIZE) {
			map.put("result", result);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}
	}
	
	@RequestMapping(value = "/selectusers")
	@ResponseBody
	public void selectAuthUserNameAndCode(String filter,HttpServletRequest request, HttpServletResponse response) throws IOException {
		/**
		 * 获取当前登录用户的公司的所有用户信息
		 */
		AuthUsers user = new AuthUsers();
		user.setCompanyCode(getUserInfo(request).get(OEM_CODE));
		user.setLanguage(CommonUtils.getLanguage(request));
		List<AuthUsers> users = authUserLogic.selectList(user, false);
		if(filter!=null&&filter.equals("true")){
			for(AuthUsers u : users){
				if(getUserInfo(request).get(USER_CODE).equals(u.getCode())){
					users.remove(u);
					break;
				}
			}
		}
		Map<String, Object> map = new HashMap<String, Object>();
		if (users != null && users.size() > DEFAULT_SIZE) {
			map.put("users", users);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}
	}

	@RequestMapping(value = "/selectcomuser")
	@ResponseBody
	public void selectCompanyNameAndCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
		/**
		 * 获取当前登录用户的公司code
		 */
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("oemcode", getUserInfo(request).get(OEM_CODE));
		map.put("language", request.getParameter("language"));
		if (request.getParameter("customer") != null) {
			map.put("type", request.getParameter("type"));
		}
		List<Companies> company = companiesLogic.selectCompanyCodeAndName(map);
		if (company != null && company.size() > DEFAULT_SIZE) {
			map = new HashMap<String, Object>();
			map.put("companys", company);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}

	}

	@RequestMapping(value = "/selectCustomer")
	@ResponseBody
	public void selectCustomer(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		if(getUserInfo(request).get(USER_TYPE).equals(CommonUtils.OEM_TYPE) || getUserInfo(request).get(USER_TYPE).equals(CommonUtils.INTEGRATOR_TYPE) ){
			map.put("oemcode", getUserInfo(request).get(OEM_CODE));
		}else if(getUserInfo(request).get(USER_TYPE).equals(CommonUtils.CUSTORER_TYPE)){
			map.put("comcode", getUserInfo(request).get(COM_CODE));
		}
		map.put("language", request.getParameter("language"));
		List<Companies> company = companiesLogic.selectCompanyByOemCode(map);
		if (company != null && company.size() > DEFAULT_SIZE) {
			map = new HashMap<String, Object>();
			map.put("list", company);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}

	}

	@RequestMapping(value = "/selectCustomerProline")
	@ResponseBody
	public void selectCustomerProline(ProductionLines productionLines, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		List<ProductionLines> lines = productionLinesLogic.selectProLinesEquipmentByCustomerCode(productionLines);
		if (lines != null && lines.size() > DEFAULT_SIZE) {
			map = new HashMap<String, Object>();
			map.put("list", lines);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}

	}

	@RequestMapping(value = "/selectCustomerEquipmentListState")
	@ResponseBody
	public void selectCustomerEquipmentListState(Equipments equipment, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> equipments = companiesLogic.selectCustomerEquipmentState(equipment);
		if (equipments != null && equipments.size() > DEFAULT_SIZE) {
			map.put("model", equipments);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}

	}

	@RequestMapping(value = "/selectEquipmentState")
	@ResponseBody
	public void selectEquipmentState(Equipments equipment, HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> model = equipmentsLogic.selectEquipmentState(equipment);
		if (model != null && model.size() > DEFAULT_SIZE) {
			map.put("model", model);
			String returnData = returnJsonAllRequest(request, response, map, SUCCESS, null);
			response.getWriter().println(returnData);
		} else {
			String returnData = returnJsonAllRequest(request, response, map, ERROR, null);
			response.getWriter().println(returnData);
		}

	}

	/**
	 * return String
	 * 
	 * @Description: 二进制流转化为图片，并保存
	 * @param @param
	 *            base64String
	 * @param @param
	 *            request
	 * @param @return
	 *            文件名
	 * @return String 返回类型
	 */
	public synchronized String storeBase64(String base64String, HttpServletRequest request) {

		// 判断文件夹是否存在，不存在则建立文件夹
		Date nowDate = new Date();

		String cate = new SimpleDateFormat("yyyyMM").format(nowDate);
		// windows下
		File file = null;
		if ("\\".equals(File.separator)) {
			file = new File(WINDOWS_UPLOAD_IMG_PATH + File.separator + cate);
		}
		// linux下
		if ("/".equals(File.separator)) {
			file = new File(LINUX_UPLOAD_IMG_PATH + File.separator + cate);
		}
		// 如果文件夹不存在则创建
		if (!file.exists() && !file.isDirectory()) {
			System.out.println("上传目录不存在");
			file.mkdirs();
		} else {
			System.out.println("上传目录存在");
		}
		String fileName = CommonUtils.getUUID() + ".png";
		// 去除图片流的开头定义
		String str_path = "";
		for (int i = 0; i < base64String.length() - 1; i++) {
			if (base64String.substring(i, i + 1).equals(",")) {
				str_path = base64String.substring(i + 1, base64String.length() - 1);
				break;
			}
		}

		try {
			// Base64解码
			byte[] b = Base64.decodeBase64(str_path);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}
			// 生成图片
			OutputStream out = new FileOutputStream(file.getPath() + File.separator + fileName);
			out.write(b);
			out.flush();
			out.close();
		} catch (Exception e) {
			logger.error("图片上传 error" , e);
			return "";
		}

		// windows下
		if ("\\".equals(File.separator)) {
			fileName = File.separator + UPLOAD_IMG_PATH + File.separator + cate + File.separator + fileName;
			fileName = fileName.replace("\\", "/");
		}
		// linux下
		if ("/".equals(File.separator)) {
			fileName = File.separator + UPLOAD_IMG_PATH + File.separator + cate + File.separator + fileName;
			fileName = fileName.replace("//", "/");
		}
		fileName = CommonUtils.WEB_ADDRESS + fileName;
		return fileName;
	}

	public String[] uploadFile(HttpServletRequest request,String fileType) throws IllegalStateException, IOException{
		String fileName = null;
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());  
		 List<String> fileNames = new ArrayList<String>();
        //判断 request 是否有文件上传,即多部分请求  
        if(multipartResolver.isMultipart(request)){  
            //转换成多部分request    
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;  
            //取得request中的所有文件名  
            Iterator<String> iter = multiRequest.getFileNames();  
           
            while(iter.hasNext()){  
                //取得上传文件  
                MultipartFile file = multiRequest.getFile(iter.next());  
                if(file != null){  
                    //取得当前上传文件的文件名称  
                    String myFileName = file.getOriginalFilename();  
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在  
                    if(myFileName.trim() !=""){  
                        System.out.println(myFileName);  
                        //重命名上传后的文件名  
                        fileName = CommonUtils.getUUID()+ file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."), file.getOriginalFilename().length()) ;  
                        //定义上传路径  
                        Date nowDate = new Date();
                        String cate = new SimpleDateFormat("yyyyMM").format(nowDate);
                		// windows下
                        File localFile = null;
                		if ("\\".equals(File.separator)) {
                			localFile = new File(WINDOWS_UPLOAD_IMG_PATH + File.separator + fileType + File.separator + cate + File.separator + fileName);
                		}
                		// linux下
                		if ("/".equals(File.separator)) {
                			localFile = new File(LINUX_UPLOAD_IMG_PATH + File.separator + fileType + File.separator + cate  + File.separator + fileName);
                		}
                		// 如果文件夹不存在则创建
                		if (!localFile.exists() && !localFile.isDirectory()) {
                			System.out.println("上传目录不存在");
                			localFile.mkdirs();
                		} else {
                			System.out.println("上传目录存在");
                		}
                        file.transferTo(localFile);  
                        // windows下
                		if ("\\".equals(File.separator)) {
                			fileName = File.separator + UPLOAD_IMG_PATH + File.separator + fileType+  File.separator + cate + File.separator + fileName;
                			fileName = fileName.replace("\\", "/");
                		}
                		// linux下
                		if ("/".equals(File.separator)) {
                			fileName = File.separator + UPLOAD_IMG_PATH + File.separator + fileType + File.separator  + cate + File.separator + fileName;
                			fileName = fileName.replace("//", "/");
                		}
                		fileName = CommonUtils.WEB_ADDRESS + fileName;
                		fileNames.add(fileName);
                    }  
                }  
                //记录上传该文件后的时间  
   /*             int finaltime = (int) System.currentTimeMillis();  
                System.out.println(finaltime - pre);  */
            }             
        }
        String[] paths = fileNames.toArray(new String[fileNames.size()]);  
		return paths; 
	}
	/**
	 * returnJsonAllRequest
	 * 
	 * @Description: 所有请求都返回json数据（解决跨域问题）
	 * @param @param
	 *            request
	 * @param @param
	 *            response
	 * @param @param
	 *            map
	 * @param @param
	 *            result 结果
	 * @param @param
	 *            object 返回数据
	 * @param @return
	 * @param @throws
	 *            JsonProcessingException 参数
	 * @return String 返回类型
	 */
	public String returnJsonAllRequest(HttpServletRequest request, HttpServletResponse response,
			Map<String, Object> map, int result, Object object) throws JsonProcessingException {
		map.put("code", result);
		map.put("success", true);
		map.put("msg", CommonUtils.SUCCESS_MSG);
		ObjectMapper mapper = null;
		if(getUserInfo(request).get(LOGIN_TYPE) == CommonUtils.LOGIN_TYPE_WEB){
			mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
		}else{
			mapper = new ObjectMappingCustomer();
		}
		if (logger.isDebugEnabled()) {
			System.err.println(mapper.writeValueAsString(map));
		}
		return mapper.writeValueAsString(map);
	}
	
	public String returnJsonAllRequest(HttpServletRequest request, HttpServletResponse response, int result, Object object) throws JsonProcessingException {
		Map<String, Object> map = new HashMap<>();
		map.put("code", result);
		map.put("msg",CommonUtils.SUCCESS_MSG);
		map.put("success", true);
		if(object !=null){
			map.put("msg", object);
		}
		ObjectMapper mapper = null;
		if(getUserInfo(request).get(LOGIN_TYPE) == CommonUtils.LOGIN_TYPE_WEB){
			mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
		}else{
			mapper = new ObjectMappingCustomer();
		}
		if (logger.isDebugEnabled()) {
			System.err.println(mapper.writeValueAsString(map));
		}
		return mapper.writeValueAsString(map);
	}
	
	public String returnJsonAllRequest(HttpServletRequest request, int result, Object object) throws JsonProcessingException {
		Map<String, Object> map = new HashMap<>();
		map.put("code", result);
		map.put("msg",CommonUtils.SUCCESS_MSG);
		map.put("success", true);
		if(object !=null){
			map.put("msg", object);
		}
		ObjectMapper mapper = null;
		if(getUserInfo(request).get(LOGIN_TYPE) == CommonUtils.LOGIN_TYPE_WEB){
			mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
		}else{
			mapper = new ObjectMappingCustomer();
		}
		if (logger.isDebugEnabled()) {
			System.err.println(mapper.writeValueAsString(map));
		}
		return mapper.writeValueAsString(map);
	}
	
	protected String getErrors(BindingResult result) {
		Map<String, Object> params = new HashMap<String, Object>();
        Map<String, Object> map = new HashMap<String, Object>();
        List<FieldError> list = result.getFieldErrors();
        for (FieldError error : list) {
            map.put(error.getField(), error.getDefaultMessage());
        }
        params.put("msg",CommonUtils.ERROR_MSG);
        params.put("success", false);
        params.put("data", map);
        return JSON.toJSONString(params);
    }
	
	@RequestMapping("/upload2")  
    public String upload2(HttpServletRequest request,HttpServletResponse response) throws IllegalStateException, IOException {  
        //创建一个通用的多部分解析器  
		System.out.println(request.getParameter("code"));
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());  
        //判断 request 是否有文件上传,即多部分请求  
        if(multipartResolver.isMultipart(request)){  
            //转换成多部分request    
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;  
            //取得request中的所有文件名  
            Iterator<String> iter = multiRequest.getFileNames();  
            while(iter.hasNext()){  
                //记录上传过程起始时的时间，用来计算上传时间  
                int pre = (int) System.currentTimeMillis();  
                //取得上传文件  
                MultipartFile file = multiRequest.getFile(iter.next());  
                if(file != null){  
                    //取得当前上传文件的文件名称  
                    String myFileName = file.getOriginalFilename();  
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在  
                    if(myFileName.trim() !=""){  
                        System.out.println(myFileName);  
                        //重命名上传后的文件名  
                        String fileName = "demoUpload" + file.getOriginalFilename();  
                        //定义上传路径  
                        String path = "H:/" + fileName;  
                        File localFile = new File(path);  
                        file.transferTo(localFile);  
                    }  
                }  
                //记录上传该文件后的时间  
                int finaltime = (int) System.currentTimeMillis();  
                System.out.println(finaltime - pre);  
            }  
              
        }  
        return "/success";  
    } 
}
